from random import Random

from http import HttpError
from gamebase import GameBase

def check_password(username, password): return username if username == password[::-1] else None

class Logic(object):
    def __init__(self, config):
        self.magic = config.magic
        self.key = config.key
        self.randomgenerator = Random();
        self.authtokens = {}
        
        self.gamebase = GameBase(config)
        
        self.commands = {
            'login': self.handle_login,
            'logout': self.handle_logout,
            'turn': self.handle_turn,
            'getturns': self.handle_getturns,
            'getgames': self.handle_getgames,
            'getmygames': self.handle_getmygames,
            'addgame': self.handle_addgame,
            'joingame': self.handle_joingame,
#            'abandongame': self.handle_abandongame
            }

    def validate(self, req):
        return ('command' in req) and \
            ('params' in req) and \
            (req['command'] in self.commands) and \
            self.key in req and \
            req[self.key] == self.magic
        
    def authenticate(self, username, auth):
        return username if username in self.authtokens and self.authtokens[username] == auth else None
        
    def login(self, username):
        if username in self.authtokens: return self.authtokens[username]
        token = unicode(self.randomgenerator.randint(0, 2**31))
        self.authtokens[username] = token
        return token
        
    def logout(self, username):
        if username not in self.authtokens: return False
        self.authtokens.pop(username)
        return True
        
    def request(self, req):
        if not self.validate(req): raise HttpError(403, content='Invalid JSON request')
        
        username = None
        if 'username' in req and 'auth' in req:
            username = self.authenticate(req['username'], req['auth'])
            if username is None: # user has logged out or invalid username/auth
                return {'response': 'loggedout'}

        command = req['command']
        handler = self.commands[command]
        response = handler(command, username, req['params'])
        
        return response
        
    def handle_login(self, command, username, params):
        # TODO: validate request

        if username is not None: self.logout(username);
    
        loginname = check_password(params['username'], params['password'])
        if(loginname is not None):
            token = self.login(loginname)
            return {'response': command, 'username': username, 'auth': token}
        else:
            return {'response': 'error', 'msg': 'Invalid password'}

    def handle_logout(self, command, username, params):
        if username is not None and self.logout(username):
            return {'response': command}
        else:
            return {'response': 'error', 'msg': 'not logged in' }

    def handle_turn(self, command, username, params):
        if username is None: raise HttpError(403, content='cannot make turn: not logged in')
    
        # TODO: validate request
        gameid = params['gameid']
        turn = params['turn']
        accepted = self.gamebase.turn(username, gameid, turn, params['newstate'])

        return {
            'response': command, 
            'accepted': accepted,
            'game': self.gamebase.getturns(gameid, max(turn-1, 0))
            }

    def handle_getturns(self, command, username, params):
        # TODO: validate request
        return {
            'reponse': command,
            'games': [self.gamebase.getturns(int(gameid), int(turn)) for gameid, turn in params]
            }
            
    def handle_getgames(self, command, username, params):
        return {
            'response': command,
            'games': self.gamebase.getgames()
            }

    def handle_getmygames(self, command, username, params):
        return {
            'response': command,
            'games': self.gamebase.getmygames(username)
            }

    def handle_addgame(self, command, username, params):
        gameid = self.gamebase.addgame(username, params['color'], params['info'])
        return {
                'response': command,
                'gameid': gameid
                }
    
    def handle_joingame(self, command, username, params):
        gameid = self.gamebase.joingame(username, params['gameid'])
        if gameid:
            return {
                'response': command,
                'gameid': gameid
                }
        else:
            return {
                'response': 'error',
                'msg': 'joingame failed'
                }

#    def handle_abandongame(self, command, username, params):
#        return {
#            'response': command,
#            'gameid': self.gamebase.abandongame(username, params['gameid'])
#            }

